/**
 * 装备基础数据采集脚本
 * 功能：循环发送1301指令，根据type和base参数收集装备基础数据
 * type 取值 1-6，当type为1-3时，base取值 0-6
 */

const WebSocket = require('ws');
const fs = require('fs');
const path = require('path');

// 测试配置
const CONFIG = {
    server: {
        host: 'cd521.xin',
        port: 8207,
        protocol: 'ws'
    },
    // 直接使用token连接
    token: '4600d9f37888dfade167489cc392c288', // 替换为你的实际token
};

class EquipmentBaseCollector {
    constructor() {
        this.ws = null;
        this.currentRequest = null; // { type, base, resolve, reject, timeout }
        this.results1301 = {}; // { [type_base]: { type, base, data } }
    }

    // 发送 1301 指令并等待对应响应
    send1301AndWait(type, base = 0, timeoutMs = 8000) {
        return new Promise((resolve, reject) => {
            try {
                // 防止并发：若上一个请求未结束，则拒绝
                if (this.currentRequest) {
                    return reject(new Error('上一个请求尚未完成'));
                }

                const payload = { c: 1301, d: { type, base, pageNum: 0 } };
                this.ws.send(JSON.stringify(payload));

                const timeout = setTimeout(() => {
                    const err = new Error(`等待 1301 响应超时, type=${type}, base=${base}`);
                    if (this.currentRequest && this.currentRequest.reject) {
                        this.currentRequest.reject(err);
                    }
                    this.currentRequest = null;
                }, timeoutMs);

                this.currentRequest = { type, base, resolve, reject, timeout };
            } catch (err) {
                reject(err);
            }
        });
    }

    // 串行循环请求 1301: type 1-6，当type为1-3时，base取值0-6
    async loop1301Sequential() {
        console.log('➡️ 开始串行请求 1301，type=1..6，当type=1-3时base=0..6');
        let successCount = 0;
        let skipCount = 0;

        for (let type = 1; type <= 6; type++) {
            // 确定base的取值范围
            const baseRange = (type >= 1 && type <= 3) ? [0, 1, 2, 3, 4, 5, 6] : [0];

            for (let base of baseRange) {
                try {
                    const resp = await this.send1301AndWait(type, base);
                    console.log(resp);
                    if (resp && resp.code === 0 && resp.list && resp.list.length > 0) {
                        const key = `${type}_${base}`;
                        const entry = { type, base, data: resp.list };
                        this.results1301[key] = entry;
                        this.writeJsonToFile(this.results1301, '装备基础数据.json');
                        successCount++;
                        console.log(`✅ Type:${type}, Base:${base} 成功采集，数据条数: ${resp.list.length}`);
                    } else {
                        // code 非 0 或没有 list，跳过
                        skipCount++;
                        console.log(`⏭️ Type:${type}, Base:${base} 跳过（无数据或错误）`);
                    }
                } catch (e) {
                    // 超时或错误：跳过
                    skipCount++;
                    console.log(`⏭️ Type:${type}, Base:${base} 跳过（错误: ${e.message}）`);
                }
                // 略微间隔，避免请求过于密集
                await this.delay(100);
            }
        }
        console.log(`✅ 1301 串行请求完成，成功: ${successCount}，跳过: ${skipCount}`);
    }

    // 延迟工具方法
    delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    // 将JSON对象保存为JSON文件
    writeJsonToFile(data, filename, outputDir = './output') {
        try {
            // 确保输出目录存在
            if (!fs.existsSync(outputDir)) {
                fs.mkdirSync(outputDir, { recursive: true });
                console.log(`📁 创建输出目录: ${outputDir}`);
            }

            // 生成完整的文件路径
            const filePath = path.join(outputDir, filename);

            // 将数据转换为格式化的JSON字符串
            const jsonString = JSON.stringify(data, null, 2);

            // 写入文件
            fs.writeFileSync(filePath, jsonString, 'utf8');

            console.log(`💾 数据已保存到文件: ${filePath}`);
            console.log(`📊 数据条数: ${Object.keys(data).length}`);

            return {
                success: true,
                filePath: filePath,
                message: '文件保存成功'
            };

        } catch (error) {
            console.error('❌ 保存文件失败:', error.message);
            return {
                success: false,
                error: error.message,
                message: '文件保存失败'
            };
        }
    }

    // WebSocket连接测试
    async testWebSocketConnection() {
        console.log('🔌 步骤1: WebSocket连接测试...');

        return new Promise((resolve, reject) => {
            try {
                const wsUrl = `ws://${CONFIG.server.host}:${CONFIG.server.port}/user-service/websocket?t=${CONFIG.token}`;
                this.ws = new WebSocket(wsUrl);

                this.ws.on('open', async () => {
                    console.log('✅ WebSocket连接成功');

                    // 保持连接的基础指令
                    this.ws.send(JSON.stringify({ c: 3 }));
                    this.ws.send(JSON.stringify({ "c": 5, "d": { "roleId": 12933 } }));
                    this.ws.send(JSON.stringify({ c: 100 }));

                    // 保持ws连接的心跳
                    setInterval(() => {
                        this.ws.send(JSON.stringify({ c: 100 }));
                    }, 20000);

                    // 开始串行 1301 采集
                    this.loop1301Sequential().then(() => {
                        console.log('🎉 装备基础数据采集完成');
                        resolve();
                    }).catch((error) => {
                        console.error('❌ 采集过程中发生错误:', error.message);
                        resolve();
                    });
                });

                this.ws.on('error', (error) => {
                    console.log('❌ WebSocket连接失败:', error.message);
                    reject(error);
                });

                this.ws.on('close', () => {
                    console.log('🔌 WebSocket连接已关闭');
                });

                this.ws.on('message', (data) => {
                    try {
                        const message = JSON.parse(data);

                        // 仅处理 1301 的串行等待
                        if (message.act_id == 1301 && this.currentRequest) {
                            clearTimeout(this.currentRequest.timeout);
                            const { resolve } = this.currentRequest;
                            this.currentRequest = null;
                            resolve(message);
                        }
                    } catch (error) {
                        console.error('❌ 消息解析失败:', data);
                    }
                });

            } catch (error) {
                reject(error);
            }
        });
    }

    // 运行完整采集流程
    async runCollection() {
        console.log('🚀 开始装备基础数据采集...\n');
        console.log('采集目标：循环发送1301指令（type 1-6，当type=1-3时base=0-6）→ 串行处理响应 → 保存有效数据\n');

        try {
            // 1. 建立WebSocket连接并开始采集
            await this.testWebSocketConnection();

            console.log('\n📊 采集完成统计:');
            console.log(`   总采集数量: ${Object.keys(this.results1301).length} 条`);
            console.log(`   输出文件: ./output/装备基础数据.json`);

        } catch (error) {
            console.error('❌ 采集过程中发生错误:', error.message);
        }
    }
}

// 运行采集
async function main() {
    console.log('🎯 装备基础数据采集模式');
    console.log('   专注于采集：循环发送1301指令、串行处理响应、保存有效数据\n');

    const collector = new EquipmentBaseCollector();
    await collector.runCollection();
}

// 如果直接运行此脚本
if (require.main === module) {
    main().catch((error) => {
        console.error('💥 采集脚本执行失败:', error.message);
        process.exit(1);
    });
}

module.exports = EquipmentBaseCollector;
